#pragma once

#include <iostream>
#include <functional>
#include "Socket.hpp"
#include "Protocol.hpp"

using namespace socket_ns;
using process_t = std::function<std::shared_ptr<Response>(std::shared_ptr<Request>)>;
class IOService
{
public:
    IOService(process_t pro) : _process(pro)
    {
    }
    ~IOService() {}

    void Excute(SockSPtr sock, InetAddr addr)
    {
        std::string packageStreamQueue;
        while (1)
        {
            // 1.接收数据
            ssize_t n = sock->Recv(&packageStreamQueue);
            if (n <= 0)
            {
                // 读取失败
                LOG(INFO, "client %s quit or recv error\n", addr.AddrStr().c_str());
                break;
            }

            // 2.报文解析，提取有效载荷
            std::string package = Decode(packageStreamQueue);
            if (package.empty())
                continue; // 为空，继续读取
            std::cout << "------------------" << std::endl;
            std::cout << "package: \n" << package << std::endl;

            // 3.提取到有效载荷，反序列化
            auto req = Factor::BuildRequest();
            req->Deserialize(package);

            // 4.业务处理，输入请求，得到应答
            auto resp = _process(req);

            // 5.序列化应答
            std::string respJson;
            resp->Serialize(&respJson);
            std::cout << "respJson: \n" << respJson << std::endl;

            // 6.添加报头
            respJson = Encode(respJson);
            std::cout << "respjson add header done: \n" << respJson << std::endl;

            // 7.发送数据
            sock->Send(respJson);
        }
    }

    process_t _process;
};